<?php

	require_once("gbif.general.php");

	class Species extends General{

		public $speciesHeaderList = array(
				"taxonID"
			,	"kingdom"
			,	"phylum"
			,	"class"
			,	"order"	
			,	"family"
			,	"genus"
			,	"species"
			,	"infraspecies"
			,	"infraspeciesRank"
			,	"authorship"
			,	"synonyms"
			,	"Reference"
			,	"vernacularName"
			,	"Countries"
			,	"Threat Status"
			,	"Year Evaluated"
			,	"Native Status"
			,	"Distribution"
		);

		public $speciesOutputHeaderList = array(
				"taxonID"
			,	"rank"
			,	"scientificName"
		);

		public $distributionHeaderList = array(
				"taxonID"
			,	"locality"
			,	"threatStatus"
			, "yearEvaluated"
			,	"nativeStatus"
			,	"distribution"
		);

		public $synonymHeaderList = array(
				"taxonID"
			,	"scientificName"
			,	"parentTaxonID"
			, "reference"
		);

		public $vernacularHeaderList = array(
				"TaxonID"
			,	"Scientific Name"
			,	"Common name"
			,	"lifestage"
			,	"language"
			,	"locality"
			,	"country"
			,	"isPlural"
			,	"isPreferred"
			,	"temporal"
			,	"sex"
			,	"organismPart"
			,	"taxonRemarks"
			,	"Reference"
		);

		public function validateVernacularData( $sheetIndex = 3 ) {
			if (!$this->fileOpen) $this->openExcel();

			$passed = true;
			$wk = $this->objPHPExcel->setActiveSheetIndex( $sheetIndex );

			$highestRow = $wk->getHighestRow();
			$highestColumn = $wk->getHighestColumn();
			$highestColumnIndex = PHPExcel_Cell::columnIndexFromString($highestColumn);

			# Builds array but removes any blank rows
			for ($row = 1; $row <= $highestRow; ++$row) {
				
				$blankRow = true;				
				for ($col = 0; $col <= $highestColumnIndex; ++$col) {
					$value = $wk->getCellByColumnAndRow($col, $row)->getValue(); // Removed utf8_decode() for unicode compatibility. bko@GBIFS on 12 Dec 11.
					# Check that data do not contain control characters that break the XML transfer format (e.g. vertical tabs).  Remove if included.
					$value = str_replace("\x0B", "", $value);  //remove all vertical tabs in sender string
#ADD MORE CONDITIONS
					$this->vernacularArray[$row][$col] = trim($value);
					if ($this->vernacularArray[$row][$col] != "") {
						$blankRow = false;
					}
				}
				if ($blankRow) {
					unset($this->vernacularArray[$row]);
				}
			}

			$this->vernacularHeader = array_shift($this->vernacularArray);
			# Check for the presence and sequence of all column headers in order to generate the proper meta.xml file
			for($i=0; $i<=count($this->vernacularHeader); $i++) {
				if ($this->vernacularHeader[$i] != $this->vernacularHeaderList[$i]) {
					$this->addError("MandatoryElement", 203, sprintf("Vernacular header columns do not match '%s' != '%s'", $this->vernacularHeader[$i], $this->vernacularHeaderList[$i]) );
					$passed = false;
				}
			}

			return( $passed );
		}
		
		public function validateSpeciesData( $sheetIndex = 2 ) {
			if (!$this->fileOpen) $this->openExcel();

			$passed = true;
			$wk = $this->objPHPExcel->setActiveSheetIndex( $sheetIndex );

			$highestRow = $wk->getHighestRow();
			$highestColumn = $wk->getHighestColumn();
			$highestColumnIndex = PHPExcel_Cell::columnIndexFromString($highestColumn);

			# Builds array but removes any blank rows
			for ($row = 1; $row <= $highestRow; ++$row) {
				
				$blankRow = true;				
				for ($col = 0; $col <= $highestColumnIndex; ++$col) {
					$value = utf8_decode($wk->getCellByColumnAndRow($col, $row)->getValue());
					# Check that data do not contain control characters that break the XML transfer format (e.g. vertical tabs).  Remove if included.
					$value = str_replace("\x0B", "", $value);  //remove all vertical tabs in sender string
#ADD MORE CONDITIONS
					$this->speciesArray[$row][$col] = trim($value);
					if ($this->speciesArray[$row][$col] != "") {
						$blankRow = false;
					}
				}
				if ($blankRow) {
					unset($this->speciesArray[$row]);
				} else {
					if ($row != 1) {
						$tmpObj->kingdom = $this->speciesArray[$row][2];
						$tmpObj->phylum = $this->speciesArray[$row][3];
						$tmpObj->class = $this->speciesArray[$row][4];
						$tmpObj->order = $this->speciesArray[$row][5];
						$tmpObj->family = $this->speciesArray[$row][6];
						$tmpObj->genus = $this->speciesArray[$row][7];
						$tmpObj->species = $this->speciesArray[$row][8];
						
						$this->addTaxa( $tmpObj );
					}
				}
			}

			$this->header = array_shift($this->speciesArray);
			# Check for the presence and sequence of all column headers in order to generate the proper meta.xml file
			for($i=0; $i<=count($this->speciesHeaderList); $i++) {
				if ($this->header[$i+1] != $this->speciesHeaderList[$i]) {
					$this->addError("MandatoryElement", 203, sprintf("Header columns do not match '%s' != '%s'", $this->header[$i+1], $this->speciesHeaderList[$i]) );
					$passed = false;
				}
			}

#			for ($i=1; $i<= count($this->speciesArray); $i++) {
			for ($i=1; $i<= 1; $i++) {
				$row = $this->speciesArray[$i-1];

				# Mandatory elements are
				$mandatoryArray = array(
						"0" => "taxonID"
				);
				
				foreach($mandatoryArray as $key => $value) {
#					print $key . $value . " $row[$key]<br>";
					if ($row[$key] == '') {
						$this->addError("MandatoryElement", 200, "$value not found on row: $i" );
						$passed = false;
					}
				}

			}

			return( $passed );
		}

		public function writeSpeciesData( $outputFile ) {
			$fp = fopen($outputFile, 'w');
			fputcsv($fp, array(
					"ID"
				,	"ParentID"
				,	"TaxonomicRank"
				,	"ScientificName"
			));
			
			if(is_array($this->taxa)) {
			foreach($this->taxa as $rec) {
				fputcsv($fp, array(
						$rec["index"]
					,	$this->taxa[$rec["parent"]]["index"]
					,	$rec["rank"]
					,	$rec["value"]
				));				
			}
			}
/*			
			if(is_array($this->speciesArray)) {
			foreach ($this->speciesArray as $row) {
				fputcsv($fp, $row );
			}
			}
*/			
			fclose($fp);
		}

		public function writeVernacularData( $outputFile ) {
			$fp = fopen($outputFile, 'w');
			fputcsv($fp, $this->vernacularHeaderList);
			if(is_array($this->vernacularArray)) {
			foreach ($this->vernacularArray as $row) {
				fputcsv($fp, $row );
			}
			}
			fclose($fp);
		}
		
		public function writeSynonymData( $outputFile ) {
			$index = 1;
			$fp = fopen($outputFile, 'w');
			fputcsv($fp, $this->synonymHeaderList);
			if(is_array($this->speciesArray)) {
			foreach ($this->speciesArray as $row) {
				$names = explode(";", $row[12]);
				if (is_array($names)) {
				foreach( $names as $name){
					if (trim($name) != "") {
						fputcsv($fp, array( 
								"syn" . $index++
							,	trim($name)
							,	$row[1]
							,	$row[13]
						));
					}
				}
				} else {
					if ($row[12] != "") {
						fputcsv($fp, array( 
								"syn" . $index++
							,	trim($row[12]) . "asdf"
							,	$row[1]
							,	$row[13]
						));
					}
				}
			}
			}
			fclose($fp);
		}

		public function writeDistributionData( $outputFile ) {
			$fp = fopen($outputFile, 'w');
			fputcsv($fp, $this->distributionHeaderList);
			if(is_array($this->speciesArray)) {
			foreach ($this->speciesArray as $row) {
				$countries = explode(";", $row[15]);
				if (is_array($countries)) {
				foreach( $countries as $country){
					if (trim($country) != "") {
						fputcsv($fp, array( 
								"s" . $row[1]
							,	trim($country)
							,	$row[16]
							,	$row[17]
							,	$row[18]
							,	$row[19]
						));
					}
				}
				} else {
					if ($row[16] != "") {
						fputcsv($fp, array( 
								"s" . $row[1]
							,	trim($row[15])
							,	$row[16]
							,	$row[17]
							,	$row[18]
							,	$row[19]
						));
					}
				}
			}
			}
			fclose($fp);
		}

		public function generateSpeciesDataMeta() {
			$this->xml = new XMLWriter();
			$this->xml->openMemory();
			$this->xml->startDocument('1.0', 'UTF-8');
			$this->xml->setIndent(4);
				$this->xml->startElement('archive');
				$this->xml->writeAttribute('xmlns', 'http://rs.tdwg.org/dwc/text/');

					$this->xml->startElement('core');
						$this->xml->writeAttribute('encoding', 'UTF-8');
						$this->xml->writeAttribute('linesTerminatedBy', "\\r" );
						$this->xml->writeAttribute('fieldsTerminatedBy', "\\t" );
						$this->xml->writeAttribute('fieldsEnclosedBy', '');
						$this->xml->writeAttribute('ignoreHeaderLines', '1');
						$this->xml->writeAttribute('rowType', 'http://rs.tdwg.org/dwc/terms/Taxon');

						$this->xml->startElement('files');
							$this->xml->writeElement('location', 'species.csv');
						$this->xml->endElement();
	
						$this->xml->startElement('id');
							$this->xml->writeAttribute('index', 0);
						$this->xml->endElement();

						$this->xml->startElement('field');
							$this->xml->writeAttribute('index', 1);
							$this->xml->writeAttribute('term', 'http://rs.tdwg.org/dwc/terms/parentNameUsageID');
						$this->xml->endElement();

						$this->xml->startElement('field');
							$this->xml->writeAttribute('index', 2);
							$this->xml->writeAttribute('term', 'http://rs.tdwg.org/dwc/terms/taxonRank');
						$this->xml->endElement();

						$this->xml->startElement('field');
							$this->xml->writeAttribute('index', 3);
							$this->xml->writeAttribute('term', 'http://rs.tdwg.org/dwc/terms/scientificName');
						$this->xml->endElement();

/*
						for($i=1; $i< count($this->speciesHeaderList); $i++) {
							$this->xml->startElement('field');
								$this->xml->writeAttribute('index', $i);
								$this->xml->writeAttribute('term', 'http://rs.tdwg.org/dwc/terms/' . $this->speciesHeaderList[$i]);
							$this->xml->endElement();
						}
*/
					$this->xml->endElement();

					$this->xml->startElement('extension');
						$this->xml->writeAttribute('encoding', 'UTF-8');
						$this->xml->writeAttribute('linesTerminatedBy', "\\r" );
						$this->xml->writeAttribute('fieldsTerminatedBy', "\\t" );
						$this->xml->writeAttribute('fieldsEnclosedBy', '');
						$this->xml->writeAttribute('ignoreHeaderLines', '1');
						$this->xml->writeAttribute('rowType', 'http://rs.tdwg.org/dwc/terms/Taxon');
					
						$this->xml->startElement('files');
							$this->xml->writeElement('location', 'vernacular.csv');
						$this->xml->endElement();
	
						$this->xml->startElement('id');
							$this->xml->writeAttribute('index', 0);
						$this->xml->endElement();
	
						for($i=1; $i< count($this->vernacularHeaderList); $i++) {
							$this->xml->startElement('field');
								$this->xml->writeAttribute('index', $i);
								$this->xml->writeAttribute('term', 'http://rs.tdwg.org/dwc/terms/' . $this->headerList[$i]);
							$this->xml->endElement();
						}

					$this->xml->endElement();

				$this->xml->endElement();
			$this->xml->endDocument();
			return( $this->xml->outputMemory() );		
		}

		public function addTaxa( $rec ) {
			static $index = 1;			
			$parent = '';
			if ($rec->kingdom != '') {
				if (!isset( $this->taxa[$rec->kingdom] ) ) {
					$this->taxa[ $rec->kingdom ] = array(
						  "rank" => "kingdom"
						,	"parent" => $parent
						,	"value" => $rec->kingdom
						,	"index" => $index++
					);
				}
			}

			$parent = $rec->kingdom . $parent;
			if ($rec->phylum != '') {
				if (!isset( $this->taxa[$rec->phylum . $parent] ) ) {
					$this->taxa[ $rec->phylum . $parent ] = array(
						  "rank" => "phylum"
						,	"parent" => $parent
						,	"value" => $rec->phylum
						,	"index" => $index++
					);
				}
			}

			$parent = $rec->phylum . $parent;
			if ($rec->class != '') {
				if (!isset( $this->taxa[$rec->class . $parent] ) ) {
					$this->taxa[ $rec->class . $parent ] = array(
						  "rank" => "class"
						,	"parent" => $parent
						,	"value" => $rec->class
						,	"index" => $index++
					);
				}
			}

			$parent = $rec->class . $parent;
			if ($rec->order != '') {
				if (!isset( $this->taxa[$rec->order . $parent] ) ) {
					$this->taxa[ $rec->order . $parent ] = array(
						  "rank" => "order"
						,	"parent" => $parent
						,	"value" => $rec->order
						,	"index" => $index++
					);
				}
			}

			$parent = $rec->order . $parent;
			if ($rec->family != '') {
				if (!isset( $this->taxa[$rec->family . $parent] ) ) {
					$this->taxa[ $rec->family . $parent ] = array(
						  "rank" => "family"
						,	"parent" => $parent
						,	"value" => $rec->family
						,	"index" => $index++
					);
				}
			}

		}
		
	}

?>